package com.scs.application.modules.msg.ram;

import com.scs.application.modules.msg.handler.MessageQueue;
import org.apache.poi.ss.formula.functions.T;

import java.io.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @description: 消息处理
 */
public class StaticMessageQueue {
    private static int size = 1;
    private static int MAX_VALUE = 1024 * size;
    private static BlockingQueue store = null;
    //实时本地存储
    private static boolean timeSave = true;

    //存储文件后缀
    public static final String SUFFIX = ".lmq";
    public static String home = MessageQueue.class.getResource("/").getPath() + "MQ/";
    public static File file = null;
    private static String fileName = "master";

    //一次发送数量
    public static int onceSend = 200;

    static {
        store = new LinkedBlockingQueue(MAX_VALUE);
        String path = home + fileName + SUFFIX;
        file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (file.exists()) {
            BlockingQueue s = synRead(file.getPath());
            if (s != null)
                store.addAll(s);
        }

    }

    public static void put(Object e) {
        if (!store.contains(e)) {
            if (store.offer(e)) {
                if (timeSave) asynWrite();
            } else
                throw new RuntimeException("队列最大容量 " + MAX_VALUE + " 当前容量 " + store.size());
        }
    }

    public static T get(Class<T> e) {
        T peek = (T)store.peek();

        if (peek == null) {
            BlockingQueue<T> s = synRead(file.getPath());
            if (s != null)
                peek = s.peek();
        }
        return peek;
    }

    public static void remove(Class<T> e) {
        if (store.contains(e)) {
            store.remove(e);
            if (timeSave) asynWrite();
        }
    }

    public static  T[] array() {
        T[] ts = (T[]) store.toArray(new T[store.size()]);
        return ts;
    }

    /**
     * 异步写入到磁盘
     */
    public static void asynWrite() {
        // 异步写入磁盘
        new Thread(new Runnable() {
            @Override
            public void run() {
                synWrite();
            }
        }).start();
    }

    /**
     * 写入到磁盘
     */
    public static void synWrite() {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(file.getPath());
            oos = new ObjectOutputStream(fos);
            oos.writeObject(store);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (fos != null)
                    fos.close();
                if (oos != null)
                    oos.close();
            } catch (Exception ex) {
            }
        }
    }

    /**
     * 读取磁盘
     *
     * @return
     */
    public static BlockingQueue synRead(String path) {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream(path);
            ois = new ObjectInputStream(fis);
            LinkedBlockingQueue s = (LinkedBlockingQueue) ois.readObject();
            return s;
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
                if (ois != null)
                    ois.close();
            } catch (Exception ex) {
            }
        }
        return null;
    }

}
